<template>
    <view class="notice-container">
        <scroll-view 
            class="notice-list" 
            :scroll-y="true" 
            @scrolltolower="loadMore"
            :refresher-enabled="true" 
            :refresher-triggered="refresherTriggered" 
            @refresherrefresh="onRefresherRefresh" 
            refresher-background="#f5f5f5"
        >
            <!-- 通知列表 -->
            <view class="notice-card" v-for="(item, index) in noticeList" :key="index" v-if="!listLoading || noticeList.length > 0" @click="gotoDetail(item)">
                <view class="notice-icon">
                    <view class="icon-box">
                        <span class="iconfont icon-tongzhi"></span>
                    </view>
                    <view class="notice-title">{{ item.title }}</view>
                </view>
                <view class="notice-content">
                    <view class="notice-text">
                        <view class="notice-text-inner">
                            <u-parse :content="item.content"></u-parse>
                        </view>
                        <view v-if="overflowFlags[index]" class="ellipsis-overlay">...</view>
                    </view>
                </view>
            </view>
            
            <!-- 占位符：当数据加载中且没有数据时显示 -->
            <view v-if="listLoading && noticeList.length === 0" class="notice-placeholder">
                <view class="notice-card" v-for="i in 6" :key="i">
                    <view class="notice-icon">
                        <view class="placeholder-icon"></view>
                        <view class="placeholder-line title"></view>
                    </view>
                    <view class="notice-content">
                        <view class="placeholder-line content"></view>
                        <view class="placeholder-line content short"></view>
                    </view>
                </view>
            </view>
            
            <!-- 列表底部提示 -->
            <view class="list-footer">
                <text v-if="listLoading">正在加载...</text>
                <text v-else-if="!listHasMore">已经加载全部</text>
            </view>
        </scroll-view>
    </view>
</template>

<script>
import { getCommunitynewsNoticeList } from '@/api/index.js'
export default {
    name: 'Notice',
    data() {
        return {
            noticeList: [],
            // 列表分页与加载状态
            listPage: 1,
            listLimit: 10,
            listHasMore: true,
            listLoading: false,
            // 下拉刷新相关
            refresherTriggered: false,
            lastRefreshTime: 0,
            refreshDebounceTime: 2000,
            // 超高省略标记数组
            overflowFlags: [],
            // 重试测量
            overflowRetry: 0,
            overflowTimer: null
        }
    },
    mounted() {
        this.getNoticeList()
    },
    onReady() {
        this.$nextTick(() => {
            this.checkOverflow(true)
        })
    },
    methods: {
        gotoDetail(item) {
            uni.navigateTo({
                url: '/views/community/notice-detail?id=' + item.id
            })
        },
        onRefresherRefresh() {
            // 防抖处理：2秒内不允许重复刷新
            const now = Date.now()
            if (now - this.lastRefreshTime < this.refreshDebounceTime) {
                this.refresherTriggered = false
                uni.showToast({
                    title: '刷新过于频繁，请稍后再试',
                    icon: 'none',
                    duration: 1500
                })
                return
            }
            
            this.lastRefreshTime = now
            this.refresherTriggered = true
            this.refreshData()
        },
        
        refreshData() {
            // 重置所有状态
            this.listPage = 1
            this.listHasMore = true
            this.noticeList = []
            
            // 加载数据
            this.getNoticeList()
        },
        
        // 获取通知列表
        async getNoticeList() {
            if (this.listLoading || !this.listHasMore) return

            this.listLoading = true

            try {
                // 调用接口获取数据
                const res = await getCommunitynewsNoticeList({ page: this.listPage, limit: this.listLimit });
                const list = (res && res.data && res.data.list) ? res.data.list : [];

                if (this.listPage === 1) {
                    this.noticeList = list
                } else {
                    this.noticeList = this.noticeList.concat(list)
                }

                // 判断是否还有更多
                this.listHasMore = list.length >= this.listLimit

                if (this.listHasMore) {
                    this.listPage += 1
                }

                // 渲染后检测是否超出高度
                this.$nextTick(() => {
                    this.checkOverflow(true)
                })
            } catch (e) {
                uni.showToast({
                    title: '加载失败，请重试',
                    icon: 'none'
                })
            } finally {
                this.listLoading = false
                // 重置下拉刷新状态
                if (this.refresherTriggered) {
                    this.refresherTriggered = false
                }
            }
        },
        
        // 检测每条富文本是否超过 110rpx（带重试）
        checkOverflow(force = false) {
            if (force) this.overflowRetry = 0
            const query = uni.createSelectorQuery().in(this)
            query.selectAll('.notice-text-inner').boundingClientRect(rects => {
                const limitPx = uni.upx2px(130)
                const needRetry = !rects || !rects.length || rects.some(r => !r || !r.height)
                if (needRetry && this.overflowRetry < 5) {
                    this.overflowRetry += 1
                    if (this.overflowTimer) clearTimeout(this.overflowTimer)
                    this.overflowTimer = setTimeout(() => {
                        this.checkOverflow()
                    }, 120)
                    return
                }
                if (!rects || !rects.length) return
                const flags = rects.map(r => (r && r.height) ? r.height > limitPx : false)
                this.overflowFlags = flags
                this.overflowRetry = 0
            }).exec()
        },
        
        // 加载更多
        loadMore() {
            if (this.listLoading) return
            if (!this.listHasMore) {
                uni.showToast({ title: '已经加载完全部了', icon: 'none' })
                return
            }
            this.getNoticeList()
        }
    }
}
</script>

<style lang="scss" scoped>
.notice-container {
    width: 100%;
    min-height: 100vh;
    background: #f5f5f5;
}

.notice-list {
    height: 100%;
    padding: 20rpx;
    box-sizing: border-box;
}

.notice-card {
    background: #fff;
    border-radius: 16rpx;
    padding: 32rpx;
    margin-bottom: 20rpx;
    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
}

.notice-icon {
    display: flex;
}

.icon-box {
    width: 40rpx;
    height: 40rpx;
    background: linear-gradient( 147deg, #53B8F3 0%, #0785CF 100%);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 10rpx;

    .iconfont {
        font-size: 22rpx;
        color: #fff;
    }
}

.notice-content {
    margin-top: 30rpx;
}

.notice-title {
    flex: 1;
    font-size: 28rpx;
    font-weight: 600;
    color: #333;
}

.notice-text {
    font-size: 28rpx;
    color: #666;
    max-height: 130rpx;
    line-height: 1.6;
    overflow: hidden;
    position: relative;
}

.notice-text-inner {
    /* 内层用于测量真实高度 */
}

.ellipsis-overlay {
    position: absolute;
    right: 0;
    bottom: 0;
    padding-left: 8rpx;
    background: #fff;
    color: #666;
}

.notice-time {
    font-size: 24rpx;
    color: #999;
    line-height: 1.4;
}

.list-footer {
    padding: 40rpx 0;
    text-align: center;
    color: #999;
    font-size: 24rpx;
}

// 占位符样式
.notice-placeholder {
    .notice-card {
        .placeholder-icon {
            width: 60rpx;
            height: 60rpx;
            background: #f0f0f0;
            border-radius: 50%;
            animation: placeholder-pulse 1.5s ease-in-out infinite;
        }
        
        .placeholder-line {
            height: 16rpx;
            background: #f0f0f0;
            border-radius: 8rpx;
            margin-bottom: 16rpx;
            animation: placeholder-pulse 1.5s ease-in-out infinite;
            
            &.title {
                width: 120rpx;
                height: 32rpx;
                margin-bottom: 16rpx;
            }
            
            &.content {
                width: 100%;
                height: 28rpx;
                margin-bottom: 16rpx;
                
                &.short {
                    width: 60%;
                }
            }
            
            &.time {
                width: 80rpx;
                height: 24rpx;
                margin-bottom: 0;
            }
        }
    }
}

@keyframes placeholder-pulse {
    0%, 100% {
        opacity: 0.6;
    }
    50% {
        opacity: 1;
    }
}
</style>